package com.hunan.api.catv.action.verification;

import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONUtil;
import com.hunan.api.catv.action.BaseAction;
import com.hunan.api.catv.annotation.MemberAuth;
import com.hunan.api.catv.common.Api;
import com.hunan.api.catv.entity.Result;
import com.hunan.api.catv.entity.dto.InviteHelpPromptDto;
import com.hunan.api.catv.service.biz.invite.MemberInviteBiz;
import com.hunan.api.catv.service.biz.system.SystemDictBiz;
import com.hunan.api.catv.utils.RedisUtils;
import com.hunan.api.catv.utils.captcha.NumberCaptcha;
import com.hunan.api.catv.utils.captcha.generator.NumberGenerator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author jiang zhuan
 * @version 1.0
 * @description 描述
 * @date 2020/11/16 0016
 * @package com.hunan.catv.app.publish.video.action.verification
 * @company 湖南有线
 */
@RestController
@RequestMapping(Api.verificationCode)
@Validated
public class VerificationCodeAction extends BaseAction {
    private static final String INVITE_HELP_PROMPT = "invite_help_prompt";

    @Autowired
    private MemberInviteBiz memberInviteBiz;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private SystemDictBiz systemDictBiz;

    @GetMapping("/get")
    public Result getVerificationCode() {
//        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
        NumberCaptcha numberCaptcha = new NumberCaptcha(200, 100, new NumberGenerator(4), 150);
        String imageBase64Data = numberCaptcha.getImageBase64Data();
        String key = UUID.fastUUID().toString(true);
        redisUtils.set("vCode_" + key, numberCaptcha.getCode(), TimeUnit.MINUTES.toSeconds(2));
        Map<String, String> map = new HashMap<>();
        map.put("serialNumber", key);
        map.put("image", imageBase64Data);
        return buildOK(map, "获取验证码成功");
    }

    @GetMapping("/get/{width}-{height}")
    public Result getVerificationCode(@PathVariable @NotNull(message = "width required") Integer width,
                                      @PathVariable @NotNull(message = "height required") Integer height,
                                      HttpSession session, HttpServletResponse response) {
//        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(width, height);
        NumberCaptcha numberCaptcha = new NumberCaptcha(width, height, new NumberGenerator(4), 150);
        session.setAttribute("verificationCode", numberCaptcha.getCode());
        try (OutputStream os = response.getOutputStream()) {
            numberCaptcha.write(os);
            os.flush();
        } catch (IOException e) {
            log.error(String.format("os异常： %s", e));
            return buildFail(false, "获取验证码失败");
        }
        return buildOK(true, "获取验证码成功");
    }

    @GetMapping("/verify/{serialNumber}-{userInputCode}-{type}")
    @MemberAuth
    public Result verify(HttpServletRequest request, @PathVariable @NotBlank(message = "serialNumber required") String serialNumber, @PathVariable @NotBlank(message = "code required") String userInputCode, @PathVariable(required = false) String type) {
        log.info("验证码接口，参数：[{}]-[{}]-[{}]-[{}]", serialNumber, userInputCode, type, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHssmm")));
        InviteHelpPromptDto inviteHelpPromptDto = Optional.ofNullable(JSONUtil.toBean(systemDictBiz.getStringByKey(INVITE_HELP_PROMPT), InviteHelpPromptDto.class)).orElse(new InviteHelpPromptDto());
        Boolean isNotRequest = redisUtils.setNX(serialNumber + userInputCode, "1", 3, TimeUnit.SECONDS);
        Map<String, Object> result = new HashMap<>();
        if (!isNotRequest) {
            result.put("verifyStatus", false);
            return buildFail(result, StringUtils.isNotBlank(inviteHelpPromptDto.getTheSameRequest())?inviteHelpPromptDto.getTheSameRequest():"操作太频繁");
        }
        String code = (String) redisUtils.get("vCode_" + serialNumber);
//        redisUtils.del("vCode_" + serialNumber);
        boolean verify = userInputCode.equalsIgnoreCase(code);
        result.put("verifyStatus", verify);
        if (verify) {
            Integer memberId = getMemberIdV2(request);
            if (StringUtils.isNotBlank(type)) {
                String deviceId = getDeviceId(request);
                log.info("助力手机设备号为：{}", deviceId);
                result = memberInviteBiz.recordAndAddMemberAsset(type, memberId, deviceId,inviteHelpPromptDto);
                result.put("verifyStatus", verify);
            }
            return buildOK(result, StringUtils.isNotBlank(inviteHelpPromptDto.getVerifySucess())?inviteHelpPromptDto.getVerifySucess():"验证码验证成功");
        } else {
            return buildFail(result, StringUtils.isNotBlank(inviteHelpPromptDto.getVerifyFail())?inviteHelpPromptDto.getVerifyFail():"验证码验证失败");
        }
    }

}
